<?php
namespace app\common\model;

use think\Model;

/**
 * 通用操作
 */
class Base extends Model
{
    /**
     * 获取全部数据
     * 
     * @param array $order 排序采用数组的方式，
     * 如果没有指定desc或者asc排序规则的话，默认为asc。
     * @return array
     */
    function getAllData($order = [])
    {
        $result = self::all(function($query) use ($order) {
            if (is_array($order) && !empty($order))
            {
                $query->order($order);
            }
        });
        return $result;
    }

    /**
     * 获取给定条件的多条数据
     * 
     * @param array|string $where 如果是字符串条件，则会自动根据主键获取多个数据
     * @param array|string $with 关联预查询
     * @param array $order 排序采用数组的方式，
     * 如果没有指定desc或者asc排序规则的话，默认为asc。
     * @return array
     */
    function getMultiData($where, $with = [], $order = [])
    {
        if ( is_string($where) )
        {
            $result = self::all($where, $with);
        } else {
            $result = $this->where($where)->select(function($query) use ($order) {
                if (is_array($order) && !empty($order))
                {
                    $query->order($order);
                }
            });
        }
        return $result;
    }

     /**
     * 获取给定条件的一条数据
     * 
     * @param array|string $where 可以是数组条件，但如果是字符串条件，则需是主键值
     * @return object
     */
    function getOneData($where)
    {
        $where = $this->getPkWhere($where);
        $result = $this->where($where)->find();
        return $result;
    }

    /**
     * 获取主键的数组条件
     * 
     * @param string|array $where 如果是字符串，则作为当前模型的主键的值，
     * @return array
     */
    protected function getPkWhere($where)
    {
        $result = [];
        if ( !empty($where) && !is_array($where) ) 
        {
            $pk = $this->getPk();
            if ( is_string($pk) ) $result = [$pk => $where];
        }
        return $result ?: $where;
    }

    /**
     * 获取给定条件的指定列的值
     * 
     * @param array $where
     * @param string $column
     * @return array
     */
    function getColumnData($where, $column)
    {
        $result = $this->where($where)->column($column);
        return $result;
    }

    /**
     * 获取给定条件的指定字段的值
     * 
     * @param string|array 如果是字符串，则作为当前模型的主键的值，
     * @param string 字段名
     * @return mixed
     */
    function getValueData($where, $field)
    {
        $where = $this->getPkWhere($where);
        $result = $this->where($where)->value($field);
        return $result;
    }

    /**
     * 给定条件更新数据
     * 
     * 注意：save()会自动把数据里的主键字段当条件,
     * 所以$data里全是主键的话，会通过数据库类更新数据
     * 
     * @param array $data 要更新所需的数据
     * @param array $where where条件数组形式
     * @return int|false
     */
    function editData($data, $where)
    {
        $pk = $this->getPk();
        $num = 0;
        foreach ((array) $pk as $key) {
            if (isset($data[$key])) {
                $num++;
            }
        }
        
        $hasPk = false; 
        // $data里是否全是主键
        if ( $num > 0 && $num === count($data) ) $hasPk = true;
        /**
         * 注意：save()更新时会自动把表的主键字段当条件，
         * 然后在要跟新的数据里把主键字段的数据都剔除掉
         */
        if ($hasPk)
        {
            $result = self::where($where)->update($data);
        } else {
            $result = $this->save( $data, $where );
        }
        
        return $result;
    }

    /**
     * 给定条件删除数据
     * 
     * @param array|string $where 建议where条件用数组形式
     * @return int 
     */
    function deleteData($where)
    {
        if (empty($where)) exit('错误：条件为空是危险操作');

        $result = $this->where($where)->delete();
        return $result;
    }
    
    /**
     * 新增数据
     * 
     * @param array $data 新增所需的数据
     * @return static
     */
    function addData($data)
    {
        $result = self::create($data);
        return $result;
    }
}
